#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Filename: buscar_ticket.py

##
# Módulos del sistema
try:
    import pygtk
    pygtk.require("2.0")
    import gtk
    import gtk.glade
except ImportError, error:
    print error
    print "Necesitas la librería gráficas gtk+pygtk"

# Utilidades
from datetime import datetime

##
# Módulos propios
try:
    from lib.database import Clasificacion, Estado, GrupoDeResolucion
    from lib.database import Empleado
    from lib.funciones_utiles import close
except ImportError, error:
    print error
    "Error en buscar_ticket"
try:
    from lib.config import WIDTH, HEIGHT
    from gui.msj_retroalimentacion import MensajeDeAdvertencia, MensajeDeError
    from gui.detalle_del_ticket import DetalleDelTicket
    from gui.derivar_ticket import DerivarTicket
    from gui.cerrar_ticket import CerrarTicket
    from lib.funciones_utiles import add_find_column
    from gui.configurar_reporte import ConfigurarReporte
except ImportError, error:
    print error
    print "Error en buscar_ticket.py"

class BuscarTicket:
    """Realiaza la actividad establecida en el CDU-02.

    Presenta la interfaz de los criterios de búsqueda de ticket.
    """
    def __init__(self, padre):
        """Constructor por defecto.

        Se levanta el archivo .glade y se preparan las cabeceras 'titulos' de
        las columnas, para mostrar el resultado.
        """
        self.gladefile = "gui/ghhp.glade"
        self.wTree = gtk.glade.XML(self.gladefile,"ConsultarTicket")
        self.window = self.wTree.get_widget("ConsultarTicket")
        self.window.resize(800, 200)
        # Establecemos el padre
        self.padre = padre
        #self.window.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        print self.padre.window
        self.window.set_transient_for(self.padre.window)
        self.hbox_79 = self.wTree.get_widget("hbox79")
        self.hbox_81 = self.wTree.get_widget("hbox81")
        self.hbox_97 = self.wTree.get_widget("hbox97")
        self.vbox_51 = self.wTree.get_widget("vbox51")
        # Creamos las cabecera de la lista de búsqueda
        self.find_view = self.wTree.get_widget("treeview14")
        self.armar_lista_resultado()
        self.lista_resultado = gtk.ListStore(str, str, str, str, str, str, str, str,
                str)
        self.find_view.set_model(self.lista_resultado)
        self.un_dict = {"on_button10_clicked": self.mostrar_resultados,
                "on_button24_clicked": self.limpiar_campos,
                "on_button31_clicked": self.close,
                "on_button45_clicked": self.cerrar_ticket,
                "on_button46_clicked": self.derivar_ticket,
                "on_button47_clicked": self.detalle_del_ticket,
                "on_button57_clicked": self.config_report,
                "on_button61_clicked": self.close,
                "on_button60_clicked": self.aceptar}
        self.wTree.signal_autoconnect(self.un_dict)
        # Widget de entrada
        # Entry
        self.legajo = self.wTree.get_widget("entry16")
        self.apellido = self.wTree.get_widget("entry17")
        self.nombre = self.wTree.get_widget("entry18")
        self.nro_ticket = self.wTree.get_widget("entry20")
        # Combobox
        self.clasificacion = self.wTree.get_widget("combobox19")
        self.clasificacion.set_model(gtk.ListStore(str))
        self.estado = self.wTree.get_widget("combobox20")
        self.estado.set_model(gtk.ListStore(str))
        self.ultimo_grupo = self.wTree.get_widget("combobox22")
        self.ultimo_grupo.set_model(gtk.ListStore(str))
        self.lista_grupos = {'Todos': None}
        self.lista_clasificaciones = {'Todas': None}
        self.lista_estados = {'Todos': None}
        self.armar_combos()
        # SpinButton
        # Fecha de apertura
        self.fa_desde_dia = self.wTree.get_widget("spinbutton41")
        self.fa_desde_mes = self.wTree.get_widget("spinbutton43")
        self.fa_desde_anio = self.wTree.get_widget("spinbutton42")
        self.fa_hasta_dia = self.wTree.get_widget("spinbutton40")
        self.fa_hasta_mes = self.wTree.get_widget("spinbutton39")
        self.fa_hasta_anio = self.wTree.get_widget("spinbutton38")
        # Fecha de último cambio
        self.fu_desde_dia = self.wTree.get_widget("spinbutton52")
        self.fu_desde_mes = self.wTree.get_widget("spinbutton51")
        self.fu_desde_anio = self.wTree.get_widget("spinbutton50")
        self.fu_hasta_dia = self.wTree.get_widget("spinbutton53")
        self.fu_hasta_mes = self.wTree.get_widget("spinbutton55")
        self.fu_hasta_anio = self.wTree.get_widget("spinbutton54")
        self.empleado = None
        self.conect_entry_enter()
        self.lista_ticket=[]

    def armar_lista_resultado(self):
        titulos = ["Nro", "Legajo", "Fecha\napertura", "Hora\napertura",
                "Usuario que\ncreo el ticket", "Clasificacion\nactual",
                "Estado\nactual", "Fecha último\ncambio estado",
                "G.R.\nactual asignado"]
        for pos,titulo in enumerate(titulos):
            add_find_column(titulo, pos, self.find_view)

    def run(self):
        #self.w_create_ticket = self.wTree.get_widget("consult_ticket")
        pass

    def conect_entry_enter(self):
        """Permite generar the activate signal para los widget"""
        def grab_focus(widget, other):
            other.grab_focus()
            self.completar_campos()

        def groups(lista, n, step=1):
            for index in xrange(0, len(lista)-(n-1), step):
                yield lista[index:index+n]

        path =(self.legajo, self.apellido)
        for from0, to in groups(path, 2):
            from0.connect("activate", grab_focus, to)

    def completar_campos(self):
        """Completará los campos de apellido y nombre.

        Busca en la base de datos el nombre y apellido del Empleado con legajo
        "nro_legajo".

        Keyword arguments:
        None
        """
        nro_legajo = self.legajo.get_text()
        if nro_legajo != '':
            # Levantar el apellido y nombre con este legajo
            consulta = Empleado.selectBy(legajo = nro_legajo)
            try:
                empleado = consulta[0]
                self.apellido.set_text(empleado.apellido)
                self.nombre.set_text(empleado.nombre)
                self.empleado = empleado
                self.nro_ticket.grab_focus()
            except IndexError, error:
                print error
                msj = "Nro. de legajo inexistente en el Sistema de Personal."
                print msj
                msj_error = MensajeDeError(msj, self.window)
                msj_error.run()
                self.legajo.set_text('')
                self.legajo.grab_focus()


    def armar_combos(self):
        """Llenará con los datos correspondientes los comboboxentry.

        Buscará en la base de dato los grupos de resolucion, las clasificaciones
        y los estados activos.

        Keyword arguments:
        """

        self.ultimo_grupo.append_text("Todos")
        self.clasificacion.append_text("Todas")
        # Llenamos el de los grupos
        consulta_grupos = GrupoDeResolucion.select()
        for grupo in consulta_grupos:
            self.lista_grupos[grupo.nombre] = grupo
            self.ultimo_grupo.append_text(grupo.nombre)
        self.ultimo_grupo.set_active(0)
        # Llenamos el de las clasificaciones
        consulta_clasificacion = Clasificacion.select()
        for clasificacion in consulta_clasificacion:
            self.lista_clasificaciones[clasificacion.nombre] = clasificacion
            self.clasificacion.append_text(clasificacion.nombre)
        self.clasificacion.set_active(0)
        # Llenamos el de los estados
        consulta_estado = Estado.select()
        for estado in consulta_estado:
            self.lista_estados[estado.nombre] = estado
            self.estado.append_text(estado.nombre)
        self.estado.append_text("Todos")
        self.estado.set_active(0)


    def datos_no_validos(self):
        """Valida los campos de fechas.

        Si fecha de apertura ó último cambio es mayor a la actual retorna True
        """
        fecha_actual = datetime.now()
        self.fecha_apertura_desde = datetime(
                self.fa_desde_anio.get_value_as_int(),
                self.fa_desde_mes.get_value_as_int(),
                self.fa_desde_dia.get_value_as_int())
        self.fecha_apertura_hasta = datetime(
                self.fa_hasta_anio.get_value_as_int(),
                self.fa_hasta_mes.get_value_as_int(),
                self.fa_hasta_dia.get_value_as_int())
        self.fecha_ultimo_cambio_desde = datetime(
                self.fu_desde_anio.get_value_as_int(),
                self.fu_desde_mes.get_value_as_int(),
                self.fu_desde_dia.get_value_as_int())
        self.fecha_ultimo_cambio_hasta = datetime(
                self.fu_hasta_anio.get_value_as_int(),
                self.fu_hasta_mes.get_value_as_int(),
                self.fu_hasta_dia.get_value_as_int())
        if (self.fecha_apertura_desde > fecha_actual or
                self.fecha_apertura_hasta > fecha_actual or
                self.fecha_ultimo_cambio_desde > fecha_actual or
                self.fecha_ultimo_cambio_hasta > fecha_actual):
            #Limpiar spines
            self.cleane_spin()
            return True, ("Las fechas de último cambio y de apertura de " +
                    "ticket\ndeben ser menores a la fecha actual")
        else:
            return False,""

    def mostrar_resultados(self, widget):
        """Llamará a la funcion buscarTicket de self.padre

        Se mostrarán todos los ticket que halla encontrado la funcion.
        """
        datos_no_validos,error = self.datos_no_validos()
        if datos_no_validos:
            msj_error = MensajeDeError(error, self.window)
            msj_error.run()
        else:
            self.window.resize(WIDTH, HEIGHT)
            nro_ticket = 0
            if self.nro_ticket.get_text():
                nro_ticket = int(self.nro_ticket.get_text())
            self.lista_ticket = self.padre.mesa_de_ayuda.buscarTicket(
                    self.empleado,
                    self.tomar_valor_combo(1),#grupo
                    self.tomar_valor_combo(2),#clasificacion
                    self.tomar_valor_combo(3),#estado
                    nro_ticket,
                    self.fecha_apertura_desde,
                    self.fecha_apertura_hasta,
                    self.fecha_ultimo_cambio_desde,
                    self.fecha_ultimo_cambio_hasta)
            if self.lista_ticket:
                self.vbox_51.hide()
                self.hbox_97.show()
                self.hbox_79.show()
                self.datos_comunes()
                # Mostramos los ticket en la lista de resultado
                for ticket in self.lista_ticket:
                    lista = [ticket.id,
                            ticket.empleado.legajo,
                            ticket.fecha_creacion.strftime("%d-%m-%Y"),
                            ticket.fecha_creacion.strftime("%H:%M"),
                            ticket.usuario_creacion.u_legajo,
                            ticket.historial_de_clasificacion[-1].clasificacion.nombre,
                            ticket.historial_de_estado[-1].estado.nombre,
                            ticket.historial_de_estado[-1].fecha.strftime("%d-%m-%Y"),
                            ticket.grupo_de_resolucion.nombre]
                    self.lista_resultado.append(lista)
                    self.padre.mesa_de_ayuda.tickets[ticket.id] = ticket#guardamos en memoria
            else:
                error = "No hay ticket que cumplan con esos requisitos."
                print error
                msj_error = MensajeDeError(error, self.window)
                msj_error.run()

    def datos_comunes(self):
        """Muestro la informacion estatica en la parte superior."""
        # Cliente
        if self.empleado:
            self.wTree.get_widget("label331").set_text(self.empleado.legajo)
            self.wTree.get_widget("label332").set_text(self.empleado.apellido)
            self.wTree.get_widget("label333").set_text(self.empleado.nombre)
        else:
            self.wTree.get_widget("frame70").hide()
        # Ticket
        if self.nro_ticket.get_text():
            self.wTree.get_widget("label334").set_text(self.nro_ticket.get_text())
        else:
            self.wTree.get_widget("label334").set_text("Todos")
        # Clasificacion del ticket    
        if self.tomar_valor_combo(2) == "Todas":
            self.wTree.get_widget("label335").set_text("Todas")
        else:
            self.wTree.get_widget("label335").set_text(self.tomar_valor_combo(2).nombre)
        # Estado del ticket
        if self.tomar_valor_combo(3) == "Todos":
            self.wTree.get_widget("label336").set_text("Todos")
        else:
            self.wTree.get_widget("label336").set_text(self.tomar_valor_combo(3).nombre)
        # Fechas
        if self.fecha_apertura_desde == self.fecha_apertura_hasta:
            self.wTree.get_widget("label340").set_text("----")
        else:
            self.wTree.get_widget("label340").set_text(
                self.fecha_apertura_desde.strftime("%d-%m-%Y") + ' ' +
                self.fecha_apertura_hasta.strftime("%d-%m-%Y")
                )
        if self.fecha_ultimo_cambio_desde == self.fecha_ultimo_cambio_hasta:
            self.wTree.get_widget("label341").set_text("----")
        else:
            self.wTree.get_widget("label341").set_text(
                self.fecha_ultimo_cambio_desde.strftime("%d-%m-%Y") + ' ' +
                self.fecha_ultimo_cambio_hasta.strftime("%d-%m-%Y")
                )
        # Grupos de resolucion
        if self.tomar_valor_combo(1) == "Todos":
            self.wTree.get_widget("label345").set_text("Todos")
        else:
            self.wTree.get_widget("label345").set_text(self.tomar_valor_combo(4).nombre)

    def tomar_valor_combo(self, combo):
        """Devuelve el valor del combo requerido.

        Retorna el valor del diccionario 'combo' que tenga como llave
        el valor de seleccion del 'combo'.

        Keyword arguments:
        combo -- type int
                    1 - Grupo de resolucion
                    2 - Clasificacion
                    3 - Estado
        """
        diccionario = {1: (self.ultimo_grupo, self.lista_grupos),
                2: (self.clasificacion, self.lista_clasificaciones),
                3: (self.estado, self.lista_estados)}

        model = diccionario[combo][0].get_model()
        index = diccionario[combo][0].get_active()
        if index and combo == 1:
            return diccionario[combo][1][model[index][0]]
        elif index and combo == 2:
            return diccionario[combo][1][model[index][0]]
        elif combo==1:
            return "Todos"
        elif combo==2:
            return "Todas"
        else:
            return diccionario[combo][1][model[index][0]]

    def derivar_ticket(self,widget):
        """Invoca a derivar ticket """

        model, path = self.find_view.get_selection().get_selected_rows()
        if path:
            pos, = path[0]
            self.derivar_ticket = DerivarTicket(self, self.lista_ticket[pos])
        else:
             error = "Para ver el detalle del ticket debe seleccionarlo"
             msj = MensajeDeError(error, self.window)
             msj.run()

    def cerrar_ticket(self, widget):
        """Invoca a cerrar ticket"""
        model, path = self.find_view.get_selection().get_selected_rows()
        if path:
            pos, = path[0]
            if (self.lista_ticket[pos].historial_de_estado[-1].estado.nombre ==
                    'Solucionado a la espera OK'):
                self.cerrar_ticket = CerrarTicket(self, self.lista_ticket[pos])
            else:
                error = "Para cerrar el ticket, su estado debe ser:"
                estado = "\n\t- Solucionado a la espera OK"
                msj = MensajeDeError(error+estado, self.window)
                msj.run()
        else:
             error = "Para ver el detalle del ticket debe seleccionarlo"
             msj = MensajeDeError(error, self.window)
             msj.run()

    def close(self,widget):
        close(self.window)

    def aceptar(self, widget):
        """
        Cierra la ventana de buscar ticket.
        """
        self.vbox_51.show()
        self.hbox_97.hide()
        self.hbox_79.hide()
        self.lista_resultado.clear()
        self.window.resize(800, 200)
        self.limpiar_campos(None)

    def limpiar_campos(self,widget):
        """Limpiará los campos.

        Recorrerá todos los widget de 'criterios de busqueda' y los pondra en
        su estado de default.
        """
        lista_entry = [self.legajo, self.nombre, self.apellido, self.nro_ticket]
        lista_combo = [self.clasificacion, self.ultimo_grupo, self.estado]
        #Limpiamos
        for entry in lista_entry:
            entry.set_text('')
        for combo in lista_combo:
            combo.set_active(0)
        self.cleane_spin()

    def cleane_spin(self):
        """Pone los spin button en sus valores de default."""
        lista_spin_1 = [self.fa_desde_dia, self.fa_desde_mes,
                self.fa_hasta_dia, self.fa_hasta_mes,
                self.fu_desde_dia, self.fu_desde_mes,
                self.fu_hasta_dia, self.fu_hasta_mes]
        lista_spin_1999 = [self.fa_desde_anio, self.fa_hasta_anio,
                self.fu_desde_anio, self.fu_hasta_anio]
        for spin in lista_spin_1:
            spin.set_value(1)
        for spin in lista_spin_1999:
            spin.set_value(1999)

    def detalle_del_ticket(self, widget):
        """
            Creamos una instancia de dialog_detalle_ticket
        """
        model, path = self.find_view.get_selection().get_selected_rows()
        if path:
            pos, = path[0]
            self.detalle_ticket = DetalleDelTicket(self,self.lista_ticket[pos])
        else:
             error = "Para ver el detalle del ticket debe seleccionarlo"
             msj = MensajeDeError(error, self.window)
             msj.run()

    def config_report(self,widget):
        print "Config Report"
        self.configurar_reporte = ConfigurarReporte(self)
